<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Form
 * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */

/** Zend_Form_Decorator_ViewHelper */
require_once 'Zend/Form/Decorator/ViewHelper.php';

/**
 * Zend_Dojo_Form_Decorator_DijitElement
 *
 * Render a dojo dijit element via a view helper
 *
 * Accepts the following options:
 * - separator: string with which to separate passed in content and generated content
 * - placement: whether to append or prepend the generated content to the passed in content
 * - helper:    the name of the view helper to use
 *
 * Assumes the view helper accepts three parameters, the name, value, and
 * optional attributes; these will be provided by the element.
 *
 * @package    Zend_Dojo
 * @subpackage Form_Decorator
 * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: DijitElement.php 18951 2009-11-12 16:26:19Z alexander $
 */
class Zend_Dojo_Form_Decorator_DijitElement extends Zend_Form_Decorator_ViewHelper
{
	/**
	 * Element attributes
	 * @var array
	 */
	protected $_attribs;

	/**
	 * Element types that represent buttons
	 * @var array
	 */
	protected $_buttonTypes = array(
        'Zend_Dojo_Form_Element_Button',
        'Zend_Form_Element_Button',
        'Zend_Form_Element_Reset',
        'Zend_Form_Element_Submit',
	);

	/**
	 * Dijit option parameters
	 * @var array
	 */
	protected $_dijitParams = array();

	/**
	 * Get element attributes
	 *
	 * @return array
	 */
	public function getElementAttribs()
	{
		if (null === $this->_attribs) {
			$this->_attribs = parent::getElementAttribs();
			if (array_key_exists('dijitParams', $this->_attribs)) {
				$this->setDijitParams($this->_attribs['dijitParams']);
				unset($this->_attribs['dijitParams']);
			}
		}

		return $this->_attribs;
	}

	/**
	 * Set a single dijit option parameter
	 *
	 * @param  string $key
	 * @param  mixed $value
	 * @return Zend_Dojo_Form_Decorator_DijitContainer
	 */
	public function setDijitParam($key, $value)
	{
		$this->_dijitParams[(string) $key] = $value;
		return $this;
	}

	/**
	 * Set dijit option parameters
	 *
	 * @param  array $params
	 * @return Zend_Dojo_Form_Decorator_DijitContainer
	 */
	public function setDijitParams(array $params)
	{
		$this->_dijitParams = array_merge($this->_dijitParams, $params);
		return $this;
	}

	/**
	 * Retrieve a single dijit option parameter
	 *
	 * @param  string $key
	 * @return mixed|null
	 */
	public function getDijitParam($key)
	{
		$this->getElementAttribs();
		$key = (string) $key;
		if (array_key_exists($key, $this->_dijitParams)) {
			return $this->_dijitParams[$key];
		}

		return null;
	}

	/**
	 * Get dijit option parameters
	 *
	 * @return array
	 */
	public function getDijitParams()
	{
		$this->getElementAttribs();
		return $this->_dijitParams;
	}

	/**
	 * Render an element using a view helper
	 *
	 * Determine view helper from 'helper' option, or, if none set, from
	 * the element type. Then call as
	 * helper($element->getName(), $element->getValue(), $element->getAttribs())
	 *
	 * @param  string $content
	 * @return string
	 * @throws Zend_Form_Decorator_Exception if element or view are not registered
	 */
	public function render($content)
	{
		$element = $this->getElement();
		$view = $element->getView();
		if (null === $view) {
			require_once 'Zend/Form/Decorator/Exception.php';
			throw new Zend_Form_Decorator_Exception('DijitElement decorator cannot render without a registered view object');
		}

		$options = null;
		$helper    = $this->getHelper();
		$separator = $this->getSeparator();
		$value     = $this->getValue($element);
		$attribs   = $this->getElementAttribs();
		$name      = $element->getFullyQualifiedName();

		$dijitParams = $this->getDijitParams();
		if ($element->isRequired()) {
			$dijitParams['required'] = true;
		}

		$id = $element->getId();
		if ($view->dojo()->hasDijit($id)) {
			trigger_error(sprintf('Duplicate dijit ID detected for id "%s; temporarily generating uniqid"', $id), E_USER_NOTICE);
			$base = $id;
			do {
				$id = $base . '-' . uniqid();
			} while ($view->dojo()->hasDijit($id));
		}
		$attribs['id'] = $id;

		if (array_key_exists('options', $attribs)) {
			$options = $attribs['options'];
		}

		$elementContent = $view->$helper($name, $value, $dijitParams, $attribs, $options);
		switch ($this->getPlacement()) {
			case self::APPEND:
				return $content . $separator . $elementContent;
			case self::PREPEND:
				return $elementContent . $separator . $content;
			default:
				return $elementContent;
		}
	}
}
